package com.inspur.edp.formserver.vmmanager.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.util.MetadataUtil;
import com.inspur.edp.formserver.viewmodel.GspViewModelElement;
import com.inspur.edp.formserver.viewmodel.json.element.ViewElementDeserializer;
import com.inspur.edp.formserver.viewmodel.json.element.ViewElementSerializer;
import com.inspur.edp.formserver.viewmodel.util.UpdateVoElementUtil;
import com.inspur.edp.formserver.vmmanager.exception.VmManagerException;
import com.inspur.edp.lcm.metadata.api.IMetadataContent;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.service.RefCommonService;
import com.inspur.edp.udt.designtime.api.entity.UnifiedDataTypeDef;
import io.iec.edp.caf.commons.exception.ExceptionLevel;
import io.iec.edp.caf.commons.utils.SpringBeanUtils;

public class UpdateVirtualVoElementWithUdtService {
  private String errorCode = "UpdateVirtualVoWithUdtService";

  public static UpdateVirtualVoElementWithUdtService getInstance() {
    return new UpdateVirtualVoElementWithUdtService();
  }

  /// <summary>
  /// 根据选中的udt元数据,更新多值udt字段信息
  /// 更新ChildElements,Mapping
  /// 说明：若为字段上选择udt，所有属性带出；若为加载更新，则仅更新使用方式为【约束】的属性。
  /// </summary>
  /// <returns>更新后字段的json序列化</returns>
  public String UpdateVariableWithRefUdt(String refUdtId, String path, String udtElementJson, boolean isFirstChoose)
  {
    RefCommonService metadataService = SpringBeanUtils.getBean(RefCommonService.class);

    GspMetadata refUdtMetadata = metadataService.getRefMetadata(refUdtId);
    return UpdateVariable(refUdtMetadata,udtElementJson,isFirstChoose);
  }
  public String UpdateVariableWithRefUdt(JsonNode node, String refUdtId, String path, String udtElementJson, boolean isFirstChoose) {
//    RefCommonService metadataService = SpringBeanUtils.getBean(RefCommonService.class);
    GspMetadata refUdtMetadata = WebControllerService.getMetadata(node,path,"",refUdtId);
    return UpdateVariable(refUdtMetadata,udtElementJson,isFirstChoose);
  }
  /**
   * 运行时选择选中的udt元数据，更新udt信息
   * @param refUdtId
   * @param path
   * @param udtElementJson
   * @param isFirstChoose
   * @return
   */
  public String UpdateVariableWithRefUdtRT(String refUdtId, String path, String udtElementJson, boolean isFirstChoose) {
    GspMetadata refUdtMetadata = MetadataUtil.getCustomMetadata(refUdtId);
    return UpdateVariable(refUdtMetadata,udtElementJson,isFirstChoose);
  }

  public String UpdateVariable(GspMetadata refUdtMetadata, String udtElementJson, boolean isFirstChoose) {
    GspViewModelElement  element;
    try {
      element= getMapper().readValue(udtElementJson, GspViewModelElement.class) ;
    } catch (JsonProcessingException e) {
      throw new RuntimeException("GspViewModel反序列化失败！");
    }
    IMetadataContent content = refUdtMetadata.getContent();
    if (content instanceof UnifiedDataTypeDef)
    {
      UpdateVoElementUtil util = new UpdateVoElementUtil();
      util.UpdateElementWithRefUdt(element, (UnifiedDataTypeDef) content, isFirstChoose);
    }
    else
    {
      throw new VmManagerException("",errorCode, "未定义的业务字段元数据类型。",null, ExceptionLevel.Error,false);
    }
    String eleJson;
    try {
      eleJson=getMapper().writeValueAsString(element);
    } catch (JsonProcessingException e) {
      throw new RuntimeException("GspViewModel序列化失败！");
    }
    return eleJson;
  }

  private ObjectMapper getMapper() {

    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    module.addDeserializer(IGspCommonField.class, new ViewElementDeserializer());
    module.addSerializer(IGspCommonField.class, new ViewElementSerializer());
    mapper.registerModule(module);
    return mapper;
  }
}
